package com.qfmy.webapp.service.impl.user;

import com.qfmy.common.constant.RedisConstant;
import com.qfmy.common.exception.BaseException;
import com.qfmy.common.login.LoginUser;
import com.qfmy.common.login.LoginUserHolder;
import com.qfmy.common.result.ResultCodeEnum;
import com.qfmy.model.entity.userInfo.SignInRecord;
import com.qfmy.model.enums.SignInStatus;
import com.qfmy.model.vo.user.SignInRecordVo;
import com.qfmy.webapp.mapper.user.SignInRecordMapper;
import com.qfmy.webapp.mapper.user.UserInfoMapper;
import com.qfmy.webapp.service.user.SignInRecordService;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Objects;

/**
 * @author 清风明月
 * @Package com.qfmy.webapp.service.impl.user
 * @date 2025/11/26
 * @description 签到纪录服务表
 */
@Service
@SuppressWarnings("all")
public class SignInRecordServiceImpl implements SignInRecordService {

    /**
     * 注入mapper
     */
    @Autowired
    private SignInRecordMapper signInRecordMapper;

    /**
     * 注入用户Mapper
     */
    @Autowired
    private UserInfoMapper userInfoMapper;

    /**
     * 注入StringRedisTemplate
     */
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 获取用户签到记录
     * @return
     */
    @Override
    public SignInRecordVo getUserSignInRecord() {
        //获取用户id
        Long userId = getCurretnUserId();
        //根据用户id获取用户签到记录
        SignInRecord signInRecord = signInRecordMapper.getUserSignInRecord(userId);
        //判断存在
        if (signInRecord == null) {
            return null;
        }
        //创建返回对象
        SignInRecordVo signInRecordVo = new SignInRecordVo();
        signInRecordVo.setLastSignDate(signInRecord.getLastSignDate());
        signInRecordVo.setCurrentContinuousDays(signInRecord.getCurrentContinuousDays());
        signInRecordVo.setIsSignedToday(signInRecord.getIsSignedToday());
        return signInRecordVo;
    }

    /**
     * 签到
     * @param coin
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void signIn(Integer coin) {
        //获取用户id
        Long userId = getCurretnUserId();
        //根据用户id获取用户签到记录
        SignInRecord signInRecord = signInRecordMapper.getUserSignInRecord(userId);
        //判断是否存在
        if (signInRecord == null) {
            signInRecord = new SignInRecord();
            signInRecord.setUserId(userId);
            signInRecord.setLastSignDate(LocalDate.now());
            signInRecord.setCurrentContinuousDays(1);
            signInRecord.setIsSignedToday(SignInStatus.SIGNED.getStatus());
            signInRecordMapper.insert(signInRecord);
        }else{
            //判断是否签到了
            if (signInRecord.getIsSignedToday().equals(SignInStatus.SIGNED.getStatus())) {
                throw new BaseException(ResultCodeEnum.SIGN_IN_ERROR);
            }
            //获取最后一次签到的时间
            LocalDate lastSignDate = signInRecord.getLastSignDate();
            boolean isLastSignYesterday = !Objects.isNull(lastSignDate) && lastSignDate.equals(LocalDate.now().minusDays(1));
            //判断是否是昨天
            if (isLastSignYesterday) {
                signInRecord.setCurrentContinuousDays(signInRecord.getCurrentContinuousDays() + 1);
            }else{
                signInRecord.setCurrentContinuousDays(1);
            }
            signInRecord.setLastSignDate(LocalDate.now());
            signInRecord.setIsSignedToday(SignInStatus.SIGNED.getStatus());
            signInRecordMapper.update(signInRecord);
        }

        //更新用户的金币
        userInfoMapper.updateAccount(userId, BigDecimal.valueOf(coin));
        //更新用户的签到收益
        stringRedisTemplate.opsForValue().increment(RedisConstant.APP_TODAY_SCORE_KEY + userId, coin);

    }

    /**
     * 获取当前用户id
     * @return
     */
    @Nullable
    @Contract(pure = true)
    private Long getCurretnUserId() {
        //获取当前用户id
        LoginUser loginUser = LoginUserHolder.getLoginUser();
        //判断是否存在
        if (loginUser == null) {
            throw new BaseException(ResultCodeEnum.TOKEN_INVALID);
        }
        return loginUser.getUserId();
    }
}
